package org.xx.armory.db;

import org.xx.armory.db.impl.AbstractDao;

import java.math.BigDecimal;
import java.util.List;

import static org.xx.armory.commons.Validators.greaterThanOrEqual;

/**
 * @author Haart
 */
public final class SampleDao
        extends AbstractDao
        implements Dao {
    private int startRowIndex;
    private int maximumRows;

    public SampleDao() {
        reset();
    }

    public List<Sample> queryAll() {
        this.checkState();

        final SqlStringBuilder sql = new SqlStringBuilder();
        sql.append("SELECT * FROM SAMPLES WHERE NAME = #name#");

        try (final Session session = getSessionFactory().newSession()) {
            return session
                    .setStartRowIndex(this.startRowIndex)
                    .setMaximumRows(this.maximumRows)
                    .newParameter("name").setValue("aa").then()
                    .query(sql.build(), new SampleMapper());
        } catch (Exception ex) {
            throw new DbException(ex);
        } finally {
            reset();
        }
    }

    public Sample queryById(
            Long id
    ) {
        this.checkState();

        final SqlStringBuilder sql = new SqlStringBuilder();
        sql.append("SELECT * FROM SAMPLES WHERE ID = #id#");

        try (final Session session = getSessionFactory().newSession()) {
            return session
                    .newParameter("id").setValue(id).then()
                    .querySingle(sql.build(), new SampleMapper())
                    .orElse(null);
        } catch (Exception ex) {
            throw new DbException(ex);
        } finally {
            reset();
        }
    }

    public long queryCount(
            Long id
    ) {
        this.checkState();

        final SqlStringBuilder sql = new SqlStringBuilder();
        sql.append("SELECT COUNT(*) FROM SAMPLES WHERE ID = #id#");

        try (final Session session = getSessionFactory().newSession()) {
            return session
                    .newParameter("id").setValue(id).then()
                    .querySingle(sql.build(), Mapper::toLong)
                    .orElse(0L);
        } catch (Exception ex) {
            throw new DbException(ex);
        } finally {
            reset();
        }
    }

    public BigDecimal querySum(
            Long id
    ) {
        this.checkState();

        final SqlStringBuilder sql = new SqlStringBuilder();
        sql.append("SELECT SUM(PRICE) FROM SAMPLES WHERE ID = #id#");

        try (final Session session = getSessionFactory().newSession()) {
            return session
                    .newParameter("id").setValue(id).then()
                    .querySingle(sql.build(), Mapper::toDecimal)
                    .orElse(BigDecimal.ZERO);
        } catch (Exception ex) {
            throw new DbException(ex);
        } finally {
            reset();
        }
    }

    public final SampleDao setStartRowIndex(
            int startRowIndex
    ) {
        greaterThanOrEqual(startRowIndex, "startRowIndex", 0);

        this.startRowIndex = startRowIndex;
        return this;
    }

    public final SampleDao setMaximumRows(
            int maximumRows
    ) {
        this.maximumRows = maximumRows;
        return this;
    }

    private void reset() {
        this.startRowIndex = 0;
        this.maximumRows = Integer.MAX_VALUE;
    }
}
